/*************************************************************************
	> File Name: chnmanager.cpp
	> Author: xuwenlong
	> Mail: myxuan475@126.com 
	> Created Time: 2019年05月08日 星期三 08时45分13秒
 ************************************************************************/
#include "chnmanager.h"
#include <stdio.h>
#include <json/json.h>
#include <utils/logger.h>
#include <transport/globalmsg.h>
#include <utils/socket_request.h>
#include <md5cpp/md5.h>
#include <utils/config.h>
#include <devices/devices.h>
#include <dbms/models.h>
#include <dbms/acquire.h>

#include "acquisition.h"

int gcd(int a,int b)
{
  return a%b?gcd(b,a%b):b;
}

ChnManager::ChnManager():
    m_iConfigLock(true)
{
}

ChnManager::~ChnManager()
{
}

void ChnManager::Start()
{
    StopChannel();
    UpdateTemplate();
    UpdateChannel();
    StartChannel();
}

void ChnManager::Stop()
{
    StopChannel();
}

ChnManager *ChnManager::instance()
{
    static ChnManager *pChnMgr = NULL;

    if (!pChnMgr)
        pChnMgr = new ChnManager();
    return pChnMgr;
}

void ChnManager::CommitData(int index)
{
    for (vector<tChannel>::iterator iter = m_listChannel.begin();
         iter != m_listChannel.end();
         iter++) {
        tChannel chnnel = *iter;
        if (chnnel.valid()) {
            chnnel->commitData(index);
        }
    }
}

void ChnManager::StartChannel()
{
    for (vector<tChannel>::iterator iter = m_listChannel.begin();
         iter != m_listChannel.end();
         iter++) {
        tChannel chnnel = *iter;
        if (chnnel.valid()) {
            chnnel->StartAcquisitor();
        }
    }
}

void ChnManager::StopChannel()
{
//    AutoLock autolock(m_chnLock);
    for (vector<tChannel>::iterator iter = m_listChannel.begin();
         iter != m_listChannel.end();
         iter++) {
        tChannel chnnel = *iter;
        if (chnnel.valid()) {
            chnnel->StopAcquisitor();
        }
    }
    m_listChannel.clear();
}

tAcquisitor ChnManager::GetAcquisitor(const deviceinfo_t& devinfo)
{
//    AutoLock autolock(m_chnLock);
    for (vector<tChannel>::iterator iter = m_listChannel.begin();
         iter != m_listChannel.end();iter++) {
        tChannel chnnel = *iter;
        if (!chnnel.valid())
            continue;
        if (chnnel->IsEqual(devinfo.trans)) {
            return chnnel->GetAcquisitor(devinfo);
        }
    }
    return NULL;
}

void ChnManager::UpdateChannel()
{
//    AutoLock autolock(m_chnLock);
    //生成采集器

    transports trans(-1);
    trans.FetchItems("*");
    vector<transmgr_t> translist = trans.gettransinfos();

    vector<transmgr_t>::iterator diter;
    for (diter = translist.begin();diter != translist.end();diter++) {
        const transmgr_t &dev = *diter;
        tChannel channel = new Channel(dev);
        m_listChannel.push_back(channel);
//        channel->StartAcquisitor();//开始采集
    }
}

void ChnManager::ClearChannels()
{
    for (vector<tChannel>::iterator iter = m_listChannel.begin();
         iter != m_listChannel.end();) {
        tChannel chnnel = *iter;
        if (!chnnel.valid())
            m_listChannel.erase(iter);
        else {
            chnnel->clearData();
            iter++;
        }
    }
}

vector<tChannel>& ChnManager::AllChannels()
{
    return m_listChannel;
}

tTemplate ChnManager::GetTemplate(S32 model)
{
    AutoLock autolock(m_iConfigLock);

    for (vector<tTemplate>::iterator iter = m_listTemplate.begin();
         iter != m_listTemplate.end();) {
        tTemplate &tmp = *iter;
        if (!tmp.valid())
            iter = m_listTemplate.erase(iter);
        else {
            if (tmp->IsEqual(model)) {
                return tmp;
            }
            iter++;
        }
    }

    tTemplate ttemp = new Template(model);
    if (!ttemp->Parse())
        return NULL;

    m_listTemplate.push_back(ttemp);
    return ttemp;
}

void ChnManager::UpdateTemplate()
{
    AutoLock autolock(m_iConfigLock);

    for (vector<tTemplate>::iterator iter = m_listTemplate.begin();
         iter != m_listTemplate.end();iter++) {
        tTemplate &tmp = *iter;
        if (tmp.valid()) {
            tmp->UpdateTemplate();
        }
    }
}

double ChnManager::DailyMemory()
{
    double total = 0;
    for (vector<tChannel>::iterator iter = m_listChannel.begin();
         iter != m_listChannel.end();) {
        tChannel chnnel = *iter;
        if (chnnel.valid()) {
            total += chnnel->dailyMemory();
        }
    }
    return total;
}